package simpledb.tx;

import simpledb.server.SimpleDB;
import simpledb.file.Block;
import simpledb.buffer.*;
import java.util.*;

/**
 * Manages the transaction's currently-pinned buffers. <br>
 * 管理事务的当前固定缓冲区。
 * 
 * @author Edward Sciore
 */
class BufferList {
  private Map<Block, Buffer> buffers = new HashMap<Block, Buffer>();
  private List<Block> pins = new ArrayList<Block>();
  private BufferMgr bufferMgr = SimpleDB.bufferMgr();

  /**
   * Returns the buffer pinned to the specified block. The method returns null
   * if the transaction has not pinned the block. <br>
   * 返回指定块的固定缓冲区。 如果事务没有固定该块，该方法返回null。
   * 
   * @param blk a reference to the disk block
   * @return the buffer pinned to that block
   */
  Buffer getBuffer(Block blk) {
    return buffers.get(blk);
  }

  /**
   * Pins the block and keeps track of the buffer internally. <br>
   * 引导块并在内部跟踪缓冲区。
   * 
   * @param blk a reference to the disk block
   */
  void pin(Block blk) {
    Buffer buff = bufferMgr.pin(blk);
    buffers.put(blk, buff);
    pins.add(blk);
  }

  /**
   * Appends a new block to the specified file and pins it. <br>
   * 将新块附加到指定的文件并将其固定。
   * 
   * @param filename the name of the file 文件名
   * @param fmtr the formatter used to initialize the new page 用于初始化新页面的格式化程序
   * @return a reference to the newly-created block 新创建块的引用
   */
  Block pinNew(String filename, PageFormatter fmtr) {
    Buffer buff = bufferMgr.pinNew(filename, fmtr);
    Block blk = buff.block();
    buffers.put(blk, buff);
    pins.add(blk);
    return blk;
  }

  /**
   * Unpins the specified block. <br>
   * 解除对指定块的固定
   * 
   * @param blk a reference to the disk block
   */
  void unpin(Block blk) {
    Buffer buff = buffers.get(blk);
    bufferMgr.unpin(buff);
    pins.remove(blk);
    if (!pins.contains(blk))
      buffers.remove(blk);
  }

  /**
   * Unpins any buffers still pinned by this transaction.<br>
   * 取消固定仍由此事务固定的任何缓冲区。
   */
  void unpinAll() {
    for (Block blk : pins) {
      Buffer buff = buffers.get(blk);
      bufferMgr.unpin(buff);
    }
    buffers.clear();
    pins.clear();
  }
}